﻿using System.Linq;
using System.Xml.Linq;
using SharePhone.Common;

namespace SharePhone.Provider.WebServices
{
    public delegate void GetWebCollectionCompletedHandler(object sender, RequestCompleteEventArgs e);

    public delegate void GetWebCompletedHandler(object sender, RequestCompleteEventArgs e);

    public delegate void GetContentTypeCompletedHandler(object sender, RequestCompleteEventArgs e);

    public class SPWebService : BaseWebService
    {
        private const string URL = "/_vti_bin/Webs.asmx";
        private const string ActionGetWebCollection = "http://schemas.microsoft.com/sharepoint/soap/GetWebCollection";
        private const string ActionGetWeb = "http://schemas.microsoft.com/sharepoint/soap/GetWeb";
        private const string ActionGetContentType = "http://schemas.microsoft.com/sharepoint/soap/GetContentType";

        private const string SoapGetWebCollection =
            @"<GetWebCollection xmlns='http://schemas.microsoft.com/sharepoint/soap/' />";

        private const string SoapGetWeb =
            @"<GetWeb xmlns='http://schemas.microsoft.com/sharepoint/soap/'><webUrl>{0}</webUrl></GetWeb>";

        private const string SoapGetContentType =
            @"<GetContentType xmlns='http://schemas.microsoft.com/sharepoint/soap/'><contentTypeId>{0}</contentTypeId></GetContentType>";

        private readonly CredentialSettings credentials;

        public SPWebService(string baseUrl, CredentialSettings credentials)
        {
            BaseUrl = baseUrl;
            this.credentials = credentials;
        }

        public event GetWebCollectionCompletedHandler GetWebCollectionCompleted;
        public event GetWebCompletedHandler GetWebCompleted;
        public event GetContentTypeCompletedHandler GetContentTypeCompleted;

        public void GetWebCollectionAsync()
        {
            GetResponse(ActionGetWebCollection, SoapGetWebCollection, GetNetworkCredential(credentials),
                        (object sender, RequestCompleteEventArgs e) =>
                            {
                                XElement result =
                                    e.Result.Descendants(XName.Get("GetWebCollectionResult",
                                                                   "http://schemas.microsoft.com/sharepoint/soap/")).
                                        FirstOrDefault();
                                OnGetWebCollectionCompleted(result);
                            });
        }

        public void GetWebAsync(string webUrl)
        {
            GetResponse(ActionGetWeb, string.Format(SoapGetWeb, webUrl), GetNetworkCredential(credentials),
                        (object sender, RequestCompleteEventArgs e) =>
                            {                                
                                XElement result =
                                    e.Result.Descendants(XName.Get("Web",
                                                                   "http://schemas.microsoft.com/sharepoint/soap/")).
                                        FirstOrDefault();
                                OnGetWebCompleted(result);
                            });
        }

        public void GetContentTypeAsync(string contentTypeId)
        {
            GetResponse(ActionGetContentType, string.Format(SoapGetContentType, contentTypeId),
                        GetNetworkCredential(credentials), (object sender, RequestCompleteEventArgs e) =>
                                                               {
                                                                   XElement result =
                                                                       e.Result.Descendants(XName.Get("ContentType",
                                                                                                      "http://schemas.microsoft.com/sharepoint/soap/"))
                                                                           .FirstOrDefault();
                                                                   OnGetContentTypeCompleted(result);
                                                               });
        }

        internal override string GetUrl()
        {
            return BaseUrl + URL;
        }

        protected void OnGetWebCollectionCompleted(XElement result)
        {
            if (GetWebCollectionCompleted != null)
                GetWebCollectionCompleted(this, new RequestCompleteEventArgs(result));
        }

        protected void OnGetWebCompleted(XElement result)
        {
            if (GetWebCompleted != null)
                GetWebCompleted(this, new RequestCompleteEventArgs(result));
        }

        protected void OnGetContentTypeCompleted(XElement result)
        {
            if (GetContentTypeCompleted != null)
                GetContentTypeCompleted(this, new RequestCompleteEventArgs(result));
        }
    }
}